package com.xunyji.demo02weixinauthorization.comm.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;

/**
 * @author AltEnter
 * @create 2019-01-13 14:44
 * @desc HTTP方法封装
 **/
@Slf4j
@Component
public class HttpUtils {
    @Autowired
    private RestTemplate restTemplate;

    /**
     * get请求方法封装【利用RestTemplate实现】
     * @param url
     * @return
     */
    public String doGetStrByRestTemplate(String url) {
        String result = null;
        result = restTemplate.getForObject(url, String.class);
        return result;
    }

    /**
     * get请求方法封装【利用RestTemplate实现】
     * @param url
     * @return
     */
    public Map doGetMapByRestTemplate(String url) {
        Map result = null;
//        RestTemplate restTemplate = new RestTemplate();
        result = restTemplate.getForObject(url, Map.class);
        return result;
    }


    /**
     * get请求方法封装【利用RestTemplate实现】
     * @param url 请求路径【不带参数的和带参数的url都可以】
     * @param params 请求路径参数
     * @return
     */
    public String doGetStrWithMapParamByRestTemplate(String url, Map<String, String> params) throws UnsupportedEncodingException {
        String result = null;

        String query = URLEncoder.encode(params.get("q"), "UTF-8");

        log.info("加密前请求参数为：" + params);

//        封装get请求的完整url
        String sendUrl = getUrlWithQueryString(url, params);
        log.info("参数加密后的请求URL为：" + sendUrl);
        result = restTemplate.getForObject(sendUrl, String.class);

        return result;
    }

    /**
     * get请求方法封装【利用RestTemplate实现】
     * @param url
     * @return
     */
    public Map doGetMapWithMapByRestTemplate(String url, Map<String, String> params) throws UnsupportedEncodingException {

        Map result = null;

        String query = URLEncoder.encode(params.get("q"), "UTF-8");

        log.info("加密前请求参数为：" + params);

//        封装get请求的完整url
        String sendUrl = getUrlWithQueryString(url, params);
        log.info("加密后请求参数为：" + sendUrl);
        result = restTemplate.getForObject(sendUrl, Map.class);
        return result;
    }

    /**
     * 将不带参数的url和Map类型的参数封装成一个带参数的url
     * @param url
     * @param params
     * @return
     */
    private static String getUrlWithQueryString(String url, Map<String, String> params) {
        if (params == null) {
            return url;
        }

        StringBuilder builder = new StringBuilder(url);
        if (url.contains("?")) {
            builder.append("&");
        } else {
            builder.append("?");
        }

        int i = 0;
        for (String key : params.keySet()) {
            String value = params.get(key);
            // 过滤空的key
            if (value == null) {
                continue;
            }

            if (i != 0) {
                builder.append('&');
            }

            builder.append(key);
            builder.append('=');
//            builder.append(encode(value)); // 如果使用RestTemplate请求时就不需要进行UrlEncode进行加密了，加密了反而会报错
            builder.append(value);

            i++;
        }

        return builder.toString();
    }

    /**
     * 对输入的字符串进行URL编码, 即转换为%20这种形式
     *
     * @param input 原文
     * @return URL编码. 如果编码失败, 则返回原文
     */
    public static String encode(String input) {
        if (input == null) {
            return "";
        }

        try {
            return URLEncoder.encode(input, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return input;
    }
}

